
package Customer;

import DTO.ShippingMethod;
import Exception.KwickKioskDBException;
import DAO.DAO;
import DTO.Address;
import DTO.Customer;
import DTO.Email;
import EmailService.EmailSender;
import Exception.EmptySet;
import Utilities.EmailTemplates;
import Utilities.ResponseMessages;
import Utilities.SimpleProtector;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * this class implements the customer management functionalities by implementing {@link ICustomerManager}
 * @author tejinder
 */
public class CustomerManager implements ICustomerManager {

    private static final Logger log =
            Logger.getLogger(CustomerManager.class.getName());
    private DAO dao;

    /**
     * constructor for this class, injecting data access object 
     * @param dao
     */
    public CustomerManager(DAO dao) {
        this.dao = dao;
    }

    /* GETTERS AND SETTERS ****************************************************/

    /**
     * default constructor
     */
    public CustomerManager() {
    }
    /* FUNCTIONALITY **********************************************************/

    /**
     * this method processes the customer registration information
     * @param customer
     * @return a string message
     */
    public String registerCustomer(Customer customer) {

        boolean registerSuccess = true;
        String encryptedPwd = "";
        int csId = 0;
        boolean alreadyRegisteredbyphone = false;
        boolean alreadyRegisteredbyemail = false;
        try {

            alreadyRegisteredbyphone = dao.isPhoneInDB(customer.getPhoneNumber());
            alreadyRegisteredbyemail = dao.isEmailInDB(customer.getEmail());

            if (!alreadyRegisteredbyphone) {
                if (!alreadyRegisteredbyemail) {
                    //dao.customerInDatabaseByEmail(customer.getEmail());
                    System.out.println(customer.getPassCode());
                    encryptedPwd = SimpleProtector.encrypt(customer.getPassCode());
                    customer.setPassCode(encryptedPwd);
                    System.out.println(encryptedPwd);

                    csId = dao.addCustomer(customer.getPassCode(),
                            customer.getFirstName(), customer.getLastName(),
                            customer.getEmail(), customer.getPhoneNumber());

                    if (registerSuccess) {
                        log.info("customer registartion successful for id" + csId);
                        String email = customer.getEmail();
                        String[] emails = {email};
                        Email emailVo = new Email();
                        emailVo.setTo(emails);
                        emailVo.setFrom(EmailTemplates.adminEmail);
                        emailVo.setEmailSubjectTxt(EmailTemplates.emailSubjectRegisteration);
                        emailVo.setEmailMsgTxt(EmailTemplates.emailBodyRegistartion + csId);
                        EmailSender.sendEmail(emailVo);
                    } else {
                        return ResponseMessages.REGISTRATION_FAILED;
                    }
                } else {
                    return ResponseMessages.ALREADY_REGISTERED_EMAIL;
                }
            } else {
                return ResponseMessages.ALREADY_REGISTERED_PHONE;
            }
        } catch (KwickKioskDBException ex) {
            return ResponseMessages.REGISTRATION_FAILED;
        } catch (Exception ex) {
            log.log(Level.SEVERE, null, ex);
            return ResponseMessages.REGISTRATION_FAILED;
        }

        return ResponseMessages.REGISTRATION_SUCCESSFUL + csId;
    }

    /**
     * this method authenticates and processes a login request
     * @param custId
     * @param password
     * @return a boolean flag
     */
    public boolean login(Integer custId, String password) {

        boolean loginSuccess = true;
        String dbPwd = "";
        String decryptedPwd = "";
        try {
            Customer customer = new Customer();
            customer = dao.getCustomer(custId);
            if(customer != null){
                dbPwd = customer.getPassCode();
                decryptedPwd = SimpleProtector.decrypt(dbPwd);
                System.out.println("decrypted pwd"+decryptedPwd);
            }else{
              loginSuccess = false;
            }
           // dbPwd = dao.getCustomer(custId).getPassCode();
           
        } catch (KwickKioskDBException ex) {
            loginSuccess = false;
        } catch (Exception ex) {
            loginSuccess = false;
            log.log(Level.SEVERE, null, ex);
        }
        if (!password.equals(decryptedPwd)) {
            loginSuccess = false;
        }
        return loginSuccess;
    }


    /**
     * this method edits the customer address information.
     * @param addressVO
     * @return
     */
     public String editCustomerAddress(Address addressVO) {
        boolean isAdded = false;
        try {
            isAdded = dao.updateAddress(addressVO);
        } catch (KwickKioskDBException ex) {
            return ResponseMessages.DATABASE_DOWN;
        } catch (Exception ex) {
            log.log(Level.SEVERE, null, ex);
        }
        if (!isAdded) {
            return ResponseMessages.ADDRESS_NOT_UPDATE_SUCCESSFUL;
        } else {
            return ResponseMessages.ADDRESS_UPDATE_SUCCESSFUL;
        }
    }
    /**
     * the method processes the request for adding a new address for new and existing customers.
     * @param addressVO
     * @return
     */
    public String addCustomerAddress(int csid,Address addressVO) {
        boolean isAdded = false;
        try {
            isAdded = dao.addAddressToCustomer(csid, addressVO.getAptNo(),
                    addressVO.getStNo(), addressVO.getStreet(), addressVO.getPostCode(),
                    addressVO.getCity(), addressVO.getProvince());
        } catch (KwickKioskDBException ex) {
            return ResponseMessages.DATABASE_DOWN;
        } catch (Exception ex) {
            log.log(Level.SEVERE, null, ex);
        }
        if (!isAdded) {
            return ResponseMessages.ADDRESS_NOT_UPDATE_SUCCESSFUL;
        } else {
            return ResponseMessages.ADDRESS_UPDATE_SUCCESSFUL;
        }
    }

    /**
     * this method edits the customer personal information
     * @param customer
     * @return
     */
   public String editCustomerInfo(Customer customer) {

        boolean editSuccess = false;

        try {
            String encryptedpwd  = SimpleProtector.encrypt(customer.getPassCode());
            customer.setPassCode(encryptedpwd);
            editSuccess = dao.updateCustomerInfo(customer);
        } catch (KwickKioskDBException ex) {
            editSuccess = false;
            return ResponseMessages.DATABASE_DOWN;
        } catch (Exception ex) {
            log.log(Level.SEVERE, null, ex);
        }
        if (!editSuccess) {
            return ResponseMessages.INFO_NOT_UPDATE_SUCCESSFUL;
        } else {
            return ResponseMessages.INFO_UPDATE_SUCCESSFUL;
        }
    }

   /**
    * this method retrieves a customer information for a particular customer id 
    * @param csid
    * @return
    * @throws Exception
    */
    public Customer getCustomerInfo(Integer csid) throws Exception {
        Customer customerL = null;
        try {
            customerL = dao.getCustomer(csid);
            String decryptedPwd = SimpleProtector.decrypt(customerL.getPassCode());
            customerL.setPassCode(decryptedPwd);
        } catch (KwickKioskDBException ex) {
            throw new Exception(ResponseMessages.DATABASE_DOWN);
            // Logger.getLogger(CustomerManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (EmptySet ex) {
            throw new Exception(ResponseMessages.EMPTY_EXCEPTION_NO_CUSTOMER);
            // Logger.getLogger(CustomerManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return customerL;
    }

    /**
     * This method retrieves and process the address list for a particular customer
     * @param custId
     * @return list of address objects 
     */
    public ArrayList<Address> getAddressList(Integer custId) {

        ArrayList<Address> addressList = null;
        try {
            addressList = dao.getCustomerAddress(custId);
        } catch (KwickKioskDBException ex) {
            Logger.getLogger(CustomerManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println(" addresses from database"+addressList.size() );
        return  addressList;
    }

   /**
    * this method retrieves the shipping methods associated with a province
    * @param province
    * @return list of shipping methods 
    */
    public ArrayList<ShippingMethod> getShipMethods(String province) {
         ArrayList<ShippingMethod> shipmethods = null;
        try {
            shipmethods = (ArrayList<ShippingMethod>) dao.getShipMethods(province).clone();
        } catch (KwickKioskDBException ex) {
            Logger.getLogger(CustomerManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return  shipmethods;
    }

  /**
   * This method processes the customer address removal request.
   * @param custId
   * @param addId
   * @return boolean flag
   */

    public Boolean removeCustomerAddress(Integer custId, Integer addId) {

        Boolean addRemove = false;
        try {
            addRemove =  dao.removeAddressToCustomer(custId, addId);
        } catch (KwickKioskDBException ex) {
            Logger.getLogger(CustomerManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        return addRemove;
    }
}
